//----------------------------------------------------------------------------
// M A R I T I M E  R E S E A R C H  I N S T I T U T E  N E T H E R L A N D S
//----------------------------------------------------------------------------
// Copyright (C) 2012 - MARIN - All rights reserved - http://www.marin.nl
//----------------------------------------------------------------------------
// Program    : mermaid
// Module     : vbm
// File       : CudaIncomingWaves.cu
//----------------------------------------------------------------------------

#include <math.h>
#include <cuda.h>
#include <cublas.h>
#include <stdio.h>
#include <sys/time.h>
#include "assertplus.h"
#include "FloatUtils.h"
#include "CudaIncomingWaves.h"

#include "CUDAPACKAGE/common/defs.h"
#include "CUDAPACKAGE/common/macros.h"
#include "CUDAPACKAGE/common/misc.h"

#include "CUDAPACKAGE/incomingwaves/wvin_comp.h"

#define NUMBER    m_wvin_spec_count + 1

/// constructor
CudaIncomingWaves::CudaIncomingWaves(const int Nx1,
                                     const int Nx2,
                                     const int wvin_spec_count)
: m_Nx1(Nx1)
, m_Nx2(Nx2)
, m_wvin_spec_count(wvin_spec_count)
, m_Nc(0)
, m_Nr(0)
, m_dwvin_N_count(0)
, m_dwvin_N_ext_ampl(0)
, m_dwvin_N_cen_ampl(0)
, m_dwvin_N_int_ampl(0)
, m_dwvin_N_ext_phase(0)
, m_dwvin_N_cen_phase(0)
, m_dwvin_N_int_phase(0)
, m_dwvin_N_ext_freq(0)
, m_dwvin_N_cen_freq(0)
, m_dwvin_N_int_freq(0)
, m_dwvin_N_ext_facphi(0)
, m_dwvin_N_cen_facphi(0)
, m_dwvin_N_int_facphi(0)
, m_dwvin_N_ext_facpsi(0)
, m_dwvin_N_cen_facpsi(0)
, m_dwvin_N_int_facpsi(0)
, m_dwvin_E_count(0)
, m_dwvin_E_ext_ampl(0)
, m_dwvin_E_cen_ampl(0)
, m_dwvin_E_int_ampl(0)
, m_dwvin_E_ext_phase(0)
, m_dwvin_E_cen_phase(0)
, m_dwvin_E_int_phase(0)
, m_dwvin_E_ext_freq(0)
, m_dwvin_E_cen_freq(0)
, m_dwvin_E_int_freq(0)
, m_dwvin_E_ext_facphi(0)
, m_dwvin_E_cen_facphi(0)
, m_dwvin_E_int_facphi(0)
, m_dwvin_E_ext_facpsi(0)
, m_dwvin_E_cen_facpsi(0)
, m_dwvin_E_int_facpsi(0)
, m_dwvin_S_count(0)
, m_dwvin_S_ext_ampl(0)
, m_dwvin_S_cen_ampl(0)
, m_dwvin_S_int_ampl(0)
, m_dwvin_S_ext_phase(0)
, m_dwvin_S_cen_phase(0)
, m_dwvin_S_int_phase(0)
, m_dwvin_S_ext_freq(0)
, m_dwvin_S_cen_freq(0)
, m_dwvin_S_int_freq(0)
, m_dwvin_S_ext_facphi(0)
, m_dwvin_S_cen_facphi(0)
, m_dwvin_S_int_facphi(0)
, m_dwvin_S_ext_facpsi(0)
, m_dwvin_S_cen_facpsi(0)
, m_dwvin_S_int_facpsi(0)
, m_dwvin_W_count(0)
, m_dwvin_W_ext_ampl(0)
, m_dwvin_W_cen_ampl(0)
, m_dwvin_W_int_ampl(0)
, m_dwvin_W_ext_phase(0)
, m_dwvin_W_cen_phase(0)
, m_dwvin_W_int_phase(0)
, m_dwvin_W_ext_freq(0)
, m_dwvin_W_cen_freq(0)
, m_dwvin_W_int_freq(0)
, m_dwvin_W_ext_facphi(0)
, m_dwvin_W_cen_facphi(0)
, m_dwvin_W_int_facphi(0)
, m_dwvin_W_ext_facpsi(0)
, m_dwvin_W_cen_facpsi(0)
, m_dwvin_W_int_facpsi(0)
, m_dzeta_in_N_int(0)
, m_dphi_in_N_int(0)
, m_dpsi_in_N_int(0)
, m_dzeta_in_E_int(0)
, m_dphi_in_E_int(0)
, m_dpsi_in_E_int(0)
, m_dzeta_in_S_int(0)
, m_dphi_in_S_int(0)
, m_dpsi_in_S_int(0)
, m_dzeta_in_W_int(0)
, m_dphi_in_W_int(0)
, m_dpsi_in_W_int(0)

, m_dzeta_in_N_ext(0)
, m_dphi_in_N_ext(0)
, m_dpsi_in_N_ext(0)
, m_dzeta_in_N_cen(0)
, m_dphi_in_N_cen(0)
, m_dpsi_in_N_cen(0)
, m_dzeta_in_E_ext(0)
, m_dphi_in_E_ext(0)
, m_dpsi_in_E_ext(0)
, m_dzeta_in_E_cen(0)
, m_dphi_in_E_cen(0)
, m_dpsi_in_E_cen(0)
, m_dzeta_in_S_ext(0)
, m_dphi_in_S_ext(0)
, m_dpsi_in_S_ext(0)
, m_dzeta_in_S_cen(0)
, m_dphi_in_S_cen(0)
, m_dpsi_in_S_cen(0)
, m_dzeta_in_W_ext(0)
, m_dphi_in_W_ext(0)
, m_dpsi_in_W_ext(0)
, m_dzeta_in_W_cen(0)
, m_dphi_in_W_cen(0)
, m_dpsi_in_W_cen(0)

, m_maxN(0)
, m_maxE(0)
, m_maxS(0)
, m_maxW(0)
, m_stream1(0)
, m_stream2(0)
, m_stream3(0)
, m_stream4(0)
, m_stream5(0)
, m_stream6(0)
, m_stream7(0)
, m_stream8(0)
, m_stream9(0)
, m_stream10(0)
, m_stream11(0)
, m_stream12(0)
{
    determineSizes();

    setup();
} // constructor


/// destructor
CudaIncomingWaves::~CudaIncomingWaves()
{
    cleanup();
} // destructor


void CudaIncomingWaves::determineSizes()
{
    m_Nc = NUM_THREADS * (int)ceil((float)(m_Nx1) / NUM_THREADS); // padded
    m_Nr = NUM_THREADS * (int)ceil((float)(m_Nx2) / NUM_THREADS); // padded
} // determineSizes


void CudaIncomingWaves::wvin_comp(const REAL timestep, const REAL pslow, 
                                  Array1D<REAL> *hzeta_in_N_ext, 
                                  Array1D<REAL> *hphi_in_N_ext, 
                                  Array1D<REAL> *hpsi_in_N_ext,
                                  Array1D<REAL> *hzeta_in_N_cen, 
                                  Array1D<REAL> *hphi_in_N_cen, 
                                  Array1D<REAL> *hpsi_in_N_cen,
                                  Array1D<REAL> *hzeta_in_N_int, 
                                  Array1D<REAL> *hphi_in_N_int, 
                                  Array1D<REAL> *hpsi_in_N_int,
                                  Array1D<REAL> *hzeta_in_E_ext, 
                                  Array1D<REAL> *hphi_in_E_ext, 
                                  Array1D<REAL> *hpsi_in_E_ext,
                                  Array1D<REAL> *hzeta_in_E_cen, 
                                  Array1D<REAL> *hphi_in_E_cen, 
                                  Array1D<REAL> *hpsi_in_E_cen,
                                  Array1D<REAL> *hzeta_in_E_int, 
                                  Array1D<REAL> *hphi_in_E_int, 
                                  Array1D<REAL> *hpsi_in_E_int,
                                  Array1D<REAL> *hzeta_in_S_ext, 
                                  Array1D<REAL> *hphi_in_S_ext, 
                                  Array1D<REAL> *hpsi_in_S_ext,
                                  Array1D<REAL> *hzeta_in_S_cen, 
                                  Array1D<REAL> *hphi_in_S_cen, 
                                  Array1D<REAL> *hpsi_in_S_cen,
                                  Array1D<REAL> *hzeta_in_S_int, 
                                  Array1D<REAL> *hphi_in_S_int, 
                                  Array1D<REAL> *hpsi_in_S_int,
                                  Array1D<REAL> *hzeta_in_W_ext, 
                                  Array1D<REAL> *hphi_in_W_ext, 
                                  Array1D<REAL> *hpsi_in_W_ext,
                                  Array1D<REAL> *hzeta_in_W_cen, 
                                  Array1D<REAL> *hphi_in_W_cen, 
                                  Array1D<REAL> *hpsi_in_W_cen,
                                  Array1D<REAL> *hzeta_in_W_int, 
                                  Array1D<REAL> *hphi_in_W_int, 
                                  Array1D<REAL> *hpsi_in_W_int)
{
    // multiple streams are used to fully address the device's resources

    // North extern
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_N_ext, m_dphi_in_N_ext, m_dpsi_in_N_ext,
                        m_dwvin_N_count,
                        m_dwvin_N_ext_ampl, 
                        m_dwvin_N_ext_phase,
                        m_dwvin_N_ext_freq,
                        m_dwvin_N_ext_facphi,
                        m_dwvin_N_ext_facpsi,
                        m_Nc, timestep, pslow, m_maxN, m_stream1);
    // South extern
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_S_ext, m_dphi_in_S_ext, m_dpsi_in_S_ext,
                        m_dwvin_S_count,
                        m_dwvin_S_ext_ampl, 
                        m_dwvin_S_ext_phase,
                        m_dwvin_S_ext_freq,
                        m_dwvin_S_ext_facphi,
                        m_dwvin_S_ext_facpsi,
                        m_Nc, timestep, pslow, m_maxS, m_stream2);

    // North center
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_N_cen, m_dphi_in_N_cen, m_dpsi_in_N_cen,
                        m_dwvin_N_count,
                        m_dwvin_N_cen_ampl, 
                        m_dwvin_N_cen_phase,
                        m_dwvin_N_cen_freq,
                        m_dwvin_N_cen_facphi,
                        m_dwvin_N_cen_facpsi,
                        m_Nc, timestep, pslow, m_maxN, m_stream3);

    // South center
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_S_cen, m_dphi_in_S_cen, m_dpsi_in_S_cen,
                        m_dwvin_S_count,
                        m_dwvin_S_cen_ampl, 
                        m_dwvin_S_cen_phase,
                        m_dwvin_S_cen_freq,
                        m_dwvin_S_cen_facphi,
                        m_dwvin_S_cen_facpsi,
                        m_Nc, timestep, pslow, m_maxS, m_stream4);

    // North intern
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_N_int, m_dphi_in_N_int, m_dpsi_in_N_int,
                        m_dwvin_N_count,
                        m_dwvin_N_int_ampl, 
                        m_dwvin_N_int_phase,
                        m_dwvin_N_int_freq,
                        m_dwvin_N_int_facphi,
                        m_dwvin_N_int_facpsi,
                        m_Nc, timestep, pslow, m_maxN, m_stream5);

    // South intern
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_S_int, m_dphi_in_S_int, m_dpsi_in_S_int,
                        m_dwvin_S_count,
                        m_dwvin_S_int_ampl, 
                        m_dwvin_S_int_phase,
                        m_dwvin_S_int_freq,
                        m_dwvin_S_int_facphi,
                        m_dwvin_S_int_facpsi,
                        m_Nc, timestep, pslow, m_maxS, m_stream6);

    // East extern
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_E_ext, m_dphi_in_E_ext, m_dpsi_in_E_ext,
                        m_dwvin_E_count,
                        m_dwvin_E_ext_ampl, 
                        m_dwvin_E_ext_phase,
                        m_dwvin_E_ext_freq,
                        m_dwvin_E_ext_facphi,
                        m_dwvin_E_ext_facpsi,
                        m_Nr, timestep, pslow, m_maxE, m_stream7);

    // West extern
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_W_ext, m_dphi_in_W_ext, m_dpsi_in_W_ext,
                        m_dwvin_W_count,
                        m_dwvin_W_ext_ampl, 
                        m_dwvin_W_ext_phase,
                        m_dwvin_W_ext_freq,
                        m_dwvin_W_ext_facphi,
                        m_dwvin_W_ext_facpsi,
                        m_Nr, timestep, pslow, m_maxW, m_stream8);

    // East center
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_E_cen, m_dphi_in_E_cen, m_dpsi_in_E_cen,
                        m_dwvin_E_count,
                        m_dwvin_E_cen_ampl, 
                        m_dwvin_E_cen_phase,
                        m_dwvin_E_cen_freq,
                        m_dwvin_E_cen_facphi,
                        m_dwvin_E_cen_facpsi,
                        m_Nr, timestep, pslow, m_maxE, m_stream9);

    // West center
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_W_cen, m_dphi_in_W_cen, m_dpsi_in_W_cen,
                        m_dwvin_W_count,
                        m_dwvin_W_cen_ampl, 
                        m_dwvin_W_cen_phase,
                        m_dwvin_W_cen_freq,
                        m_dwvin_W_cen_facphi,
                        m_dwvin_W_cen_facpsi,
                        m_Nr, timestep, pslow, m_maxW, m_stream10);

    // East intern
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_E_int, m_dphi_in_E_int, m_dpsi_in_E_int,
                        m_dwvin_E_count,
                        m_dwvin_E_int_ampl, 
                        m_dwvin_E_int_phase,
                        m_dwvin_E_int_freq,
                        m_dwvin_E_int_facphi,
                        m_dwvin_E_int_facpsi,
                        m_Nr, timestep, pslow, m_maxE, m_stream9);

    // West intern
    incomingwaves::wvin_comp<REAL>(m_dzeta_in_W_int, m_dphi_in_W_int, m_dpsi_in_W_int,
                        m_dwvin_W_count,
                        m_dwvin_W_int_ampl, 
                        m_dwvin_W_int_phase,
                        m_dwvin_W_int_freq,
                        m_dwvin_W_int_facphi,
                        m_dwvin_W_int_facpsi,
                        m_Nr, timestep, pslow, m_maxW, m_stream12);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_N_ext, m_dzeta_in_N_ext, m_stream1);
    common::getGpu1DVectorAsync<REAL>(hphi_in_N_ext,  m_dphi_in_N_ext,  m_stream1);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_N_ext,  m_dpsi_in_N_ext,  m_stream1);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_S_ext, m_dzeta_in_S_ext, m_stream2);
    common::getGpu1DVectorAsync<REAL>(hphi_in_S_ext,  m_dphi_in_S_ext,  m_stream2);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_S_ext,  m_dpsi_in_S_ext,  m_stream2);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_N_cen, m_dzeta_in_N_cen, m_stream3);
    common::getGpu1DVectorAsync<REAL>(hphi_in_N_cen,  m_dphi_in_N_cen,  m_stream3);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_N_cen,  m_dpsi_in_N_cen,  m_stream3);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_S_cen, m_dzeta_in_S_cen, m_stream4);
    common::getGpu1DVectorAsync<REAL>(hphi_in_S_cen,  m_dphi_in_S_cen,  m_stream4);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_S_cen,  m_dpsi_in_S_cen,  m_stream4);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_N_int, m_dzeta_in_N_int, m_stream5);
    common::getGpu1DVectorAsync<REAL>(hphi_in_N_int,  m_dphi_in_N_int,  m_stream5);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_N_int,  m_dpsi_in_N_int,  m_stream5);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_S_int, m_dzeta_in_S_int, m_stream6);
    common::getGpu1DVectorAsync<REAL>(hphi_in_S_int,  m_dphi_in_S_int,  m_stream6);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_S_int,  m_dpsi_in_S_int,  m_stream6);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_E_ext, m_dzeta_in_E_ext, m_stream7);
    common::getGpu1DVectorAsync<REAL>(hphi_in_E_ext,  m_dphi_in_E_ext,  m_stream7);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_E_ext,  m_dpsi_in_E_ext,  m_stream7);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_W_ext, m_dzeta_in_W_ext, m_stream8);
    common::getGpu1DVectorAsync<REAL>(hphi_in_W_ext,  m_dphi_in_W_ext,  m_stream8);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_W_ext,  m_dpsi_in_W_ext,  m_stream8);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_E_cen, m_dzeta_in_E_cen, m_stream9);
    common::getGpu1DVectorAsync<REAL>(hphi_in_E_cen,  m_dphi_in_E_cen,  m_stream9);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_E_cen,  m_dpsi_in_E_cen,  m_stream9);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_W_cen, m_dzeta_in_W_cen, m_stream10);
    common::getGpu1DVectorAsync<REAL>(hphi_in_W_cen,  m_dphi_in_W_cen,  m_stream10);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_W_cen,  m_dpsi_in_W_cen,  m_stream10);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_E_int, m_dzeta_in_E_int, m_stream11);
    common::getGpu1DVectorAsync<REAL>(hphi_in_E_int,  m_dphi_in_E_int,  m_stream11);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_E_int,  m_dpsi_in_E_int,  m_stream11);

    common::getGpu1DVectorAsync<REAL>(hzeta_in_W_int, m_dzeta_in_W_int, m_stream12);
    common::getGpu1DVectorAsync<REAL>(hphi_in_W_int,  m_dphi_in_W_int,  m_stream12);
    common::getGpu1DVectorAsync<REAL>(hpsi_in_W_int,  m_dpsi_in_W_int,  m_stream12);
}


void CudaIncomingWaves::setup()
{
    cudaStreamCreate(&m_stream1);
    cudaStreamCreate(&m_stream2);
    cudaStreamCreate(&m_stream3);
    cudaStreamCreate(&m_stream4);
    cudaStreamCreate(&m_stream5);
    cudaStreamCreate(&m_stream6);
    cudaStreamCreate(&m_stream7);
    cudaStreamCreate(&m_stream8);
    cudaStreamCreate(&m_stream9);
    cudaStreamCreate(&m_stream10);
    cudaStreamCreate(&m_stream11);
    cudaStreamCreate(&m_stream12);

    m_dwvin_N_count      = common::initGpuVector<int, 1>(m_Nc, 0);
    m_dwvin_N_ext_ampl   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_cen_ampl   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_int_ampl   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_ext_phase  = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_cen_phase  = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_int_phase  = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_ext_freq   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_cen_freq   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_int_freq   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_ext_facphi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_cen_facphi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_int_facphi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_ext_facpsi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_cen_facpsi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_N_int_facpsi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);

    m_dwvin_E_count      = common::initGpuVector<int, 1>(m_Nr, 0);
    m_dwvin_E_ext_ampl   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_cen_ampl   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_int_ampl   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_ext_phase  = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_cen_phase  = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_int_phase  = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_ext_freq   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_cen_freq   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_int_freq   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_ext_facphi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_cen_facphi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_int_facphi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_ext_facpsi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_cen_facpsi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_E_int_facpsi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);

    m_dwvin_S_count      = common::initGpuVector<int, 1>(m_Nc, 0);
    m_dwvin_S_ext_ampl   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_cen_ampl   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_int_ampl   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_ext_phase  = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_cen_phase  = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_int_phase  = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_ext_freq   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_cen_freq   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_int_freq   = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_ext_facphi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_cen_facphi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_int_facphi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_ext_facpsi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_cen_facpsi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);
    m_dwvin_S_int_facpsi = common::initGpuVector<REAL,1>(m_Nc * NUMBER, 0);

    m_dwvin_W_count      = common::initGpuVector<int, 1>(m_Nr, 0);
    m_dwvin_W_ext_ampl   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_cen_ampl   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_int_ampl   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_ext_phase  = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_cen_phase  = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_int_phase  = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_ext_freq   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_cen_freq   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_int_freq   = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_ext_facphi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_cen_facphi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_int_facphi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_ext_facpsi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_cen_facpsi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);
    m_dwvin_W_int_facpsi = common::initGpuVector<REAL,1>(m_Nr * NUMBER, 0);

    m_dzeta_in_N_int     = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dphi_in_N_int      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dpsi_in_N_int      = common::initGpuVector<REAL,1>(m_Nc, 0);

    m_dzeta_in_E_int     = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dphi_in_E_int      = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dpsi_in_E_int      = common::initGpuVector<REAL,1>(m_Nr, 0);

    m_dzeta_in_S_int     = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dphi_in_S_int      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dpsi_in_S_int      = common::initGpuVector<REAL,1>(m_Nc, 0);

    m_dzeta_in_W_int     = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dphi_in_W_int      = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dpsi_in_W_int      = common::initGpuVector<REAL,1>(m_Nr, 0);

    // Note: The same vectors are used by CudaWavesComputer!
    //       In the current version the next data is copied 
    //       H2D and D2H

    m_dzeta_in_N_ext     = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dphi_in_N_ext      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dpsi_in_N_ext      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dzeta_in_N_cen     = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dphi_in_N_cen      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dpsi_in_N_cen      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dzeta_in_E_ext     = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dphi_in_E_ext      = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dpsi_in_E_ext      = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dzeta_in_E_cen     = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dphi_in_E_cen      = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dpsi_in_E_cen      = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dzeta_in_S_ext     = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dphi_in_S_ext      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dpsi_in_S_ext      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dzeta_in_S_cen     = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dphi_in_S_cen      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dpsi_in_S_cen      = common::initGpuVector<REAL,1>(m_Nc, 0);
    m_dzeta_in_W_ext     = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dphi_in_W_ext      = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dpsi_in_W_ext      = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dzeta_in_W_cen     = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dphi_in_W_cen      = common::initGpuVector<REAL,1>(m_Nr, 0);
    m_dpsi_in_W_cen      = common::initGpuVector<REAL,1>(m_Nr, 0);

}

void CudaIncomingWaves::cleanup()
{
    // North
    common::freeGpuVector<int >(m_dwvin_N_count);
    common::freeGpuVector<REAL>(m_dwvin_N_ext_ampl);
    common::freeGpuVector<REAL>(m_dwvin_N_cen_ampl);
    common::freeGpuVector<REAL>(m_dwvin_N_int_ampl);
    common::freeGpuVector<REAL>(m_dwvin_N_ext_phase);
    common::freeGpuVector<REAL>(m_dwvin_N_cen_phase);
    common::freeGpuVector<REAL>(m_dwvin_N_int_phase);
    common::freeGpuVector<REAL>(m_dwvin_N_ext_freq);
    common::freeGpuVector<REAL>(m_dwvin_N_cen_freq);
    common::freeGpuVector<REAL>(m_dwvin_N_int_freq);
    common::freeGpuVector<REAL>(m_dwvin_N_ext_facphi);
    common::freeGpuVector<REAL>(m_dwvin_N_cen_facphi);
    common::freeGpuVector<REAL>(m_dwvin_N_int_facphi);
    common::freeGpuVector<REAL>(m_dwvin_N_ext_facpsi);
    common::freeGpuVector<REAL>(m_dwvin_N_cen_facpsi);
    common::freeGpuVector<REAL>(m_dwvin_N_int_facpsi);

    // East
    common::freeGpuVector<int >(m_dwvin_E_count);
    common::freeGpuVector<REAL>(m_dwvin_E_ext_ampl);
    common::freeGpuVector<REAL>(m_dwvin_E_cen_ampl);
    common::freeGpuVector<REAL>(m_dwvin_E_int_ampl);
    common::freeGpuVector<REAL>(m_dwvin_E_ext_phase);
    common::freeGpuVector<REAL>(m_dwvin_E_cen_phase);
    common::freeGpuVector<REAL>(m_dwvin_E_int_phase);
    common::freeGpuVector<REAL>(m_dwvin_E_ext_freq);
    common::freeGpuVector<REAL>(m_dwvin_E_cen_freq);
    common::freeGpuVector<REAL>(m_dwvin_E_int_freq);
    common::freeGpuVector<REAL>(m_dwvin_E_ext_facphi);
    common::freeGpuVector<REAL>(m_dwvin_E_cen_facphi);
    common::freeGpuVector<REAL>(m_dwvin_E_int_facphi);
    common::freeGpuVector<REAL>(m_dwvin_E_ext_facpsi);
    common::freeGpuVector<REAL>(m_dwvin_E_cen_facpsi);
    common::freeGpuVector<REAL>(m_dwvin_E_int_facpsi);

    // South
    common::freeGpuVector<int >(m_dwvin_S_count);
    common::freeGpuVector<REAL>(m_dwvin_S_ext_ampl);
    common::freeGpuVector<REAL>(m_dwvin_S_cen_ampl);
    common::freeGpuVector<REAL>(m_dwvin_S_int_ampl);
    common::freeGpuVector<REAL>(m_dwvin_S_ext_phase);
    common::freeGpuVector<REAL>(m_dwvin_S_cen_phase);
    common::freeGpuVector<REAL>(m_dwvin_S_int_phase);
    common::freeGpuVector<REAL>(m_dwvin_S_ext_freq);
    common::freeGpuVector<REAL>(m_dwvin_S_cen_freq);
    common::freeGpuVector<REAL>(m_dwvin_S_int_freq);
    common::freeGpuVector<REAL>(m_dwvin_S_ext_facphi);
    common::freeGpuVector<REAL>(m_dwvin_S_cen_facphi);
    common::freeGpuVector<REAL>(m_dwvin_S_int_facphi);
    common::freeGpuVector<REAL>(m_dwvin_S_ext_facpsi);
    common::freeGpuVector<REAL>(m_dwvin_S_cen_facpsi);
    common::freeGpuVector<REAL>(m_dwvin_S_int_facpsi);

    // West
    common::freeGpuVector<int >(m_dwvin_W_count);
    common::freeGpuVector<REAL>(m_dwvin_W_ext_ampl);
    common::freeGpuVector<REAL>(m_dwvin_W_cen_ampl);
    common::freeGpuVector<REAL>(m_dwvin_W_int_ampl);
    common::freeGpuVector<REAL>(m_dwvin_W_ext_phase);
    common::freeGpuVector<REAL>(m_dwvin_W_cen_phase);
    common::freeGpuVector<REAL>(m_dwvin_W_int_phase);
    common::freeGpuVector<REAL>(m_dwvin_W_ext_freq);
    common::freeGpuVector<REAL>(m_dwvin_W_cen_freq);
    common::freeGpuVector<REAL>(m_dwvin_W_int_freq);
    common::freeGpuVector<REAL>(m_dwvin_W_ext_facphi);
    common::freeGpuVector<REAL>(m_dwvin_W_cen_facphi);
    common::freeGpuVector<REAL>(m_dwvin_W_int_facphi);
    common::freeGpuVector<REAL>(m_dwvin_W_ext_facpsi);
    common::freeGpuVector<REAL>(m_dwvin_W_cen_facpsi);
    common::freeGpuVector<REAL>(m_dwvin_W_int_facpsi);

    // Extra (not already used by CudaWavesComputer)
    common::freeGpuVector<REAL>(m_dzeta_in_N_int);
    common::freeGpuVector<REAL>(m_dphi_in_N_int);
    common::freeGpuVector<REAL>(m_dpsi_in_N_int);

    common::freeGpuVector<REAL>(m_dzeta_in_E_int);
    common::freeGpuVector<REAL>(m_dphi_in_E_int);
    common::freeGpuVector<REAL>(m_dpsi_in_E_int);

    common::freeGpuVector<REAL>(m_dzeta_in_S_int);
    common::freeGpuVector<REAL>(m_dphi_in_S_int);
    common::freeGpuVector<REAL>(m_dpsi_in_S_int);

    common::freeGpuVector<REAL>(m_dzeta_in_W_int);
    common::freeGpuVector<REAL>(m_dphi_in_W_int);
    common::freeGpuVector<REAL>(m_dpsi_in_W_int);

    // Note: The same vectors are used by CudaWavesComputer!
    //       In the current version the next data is copied 
    //       H2D and D2H

    common::freeGpuVector<REAL>(m_dzeta_in_N_ext);
    common::freeGpuVector<REAL>(m_dphi_in_N_ext);
    common::freeGpuVector<REAL>(m_dpsi_in_N_ext);
    common::freeGpuVector<REAL>(m_dzeta_in_N_cen);
    common::freeGpuVector<REAL>(m_dphi_in_N_cen);
    common::freeGpuVector<REAL>(m_dpsi_in_N_cen);

    common::freeGpuVector<REAL>(m_dzeta_in_E_ext);
    common::freeGpuVector<REAL>(m_dphi_in_E_ext);
    common::freeGpuVector<REAL>(m_dpsi_in_E_ext);
    common::freeGpuVector<REAL>(m_dzeta_in_E_cen);
    common::freeGpuVector<REAL>(m_dphi_in_E_cen);
    common::freeGpuVector<REAL>(m_dpsi_in_E_cen);

    common::freeGpuVector<REAL>(m_dzeta_in_S_ext);
    common::freeGpuVector<REAL>(m_dphi_in_S_ext);
    common::freeGpuVector<REAL>(m_dpsi_in_S_ext);
    common::freeGpuVector<REAL>(m_dzeta_in_S_cen);
    common::freeGpuVector<REAL>(m_dphi_in_S_cen);
    common::freeGpuVector<REAL>(m_dpsi_in_S_cen);

    common::freeGpuVector<REAL>(m_dzeta_in_W_ext);
    common::freeGpuVector<REAL>(m_dphi_in_W_ext);
    common::freeGpuVector<REAL>(m_dpsi_in_W_ext);
    common::freeGpuVector<REAL>(m_dzeta_in_W_cen);
    common::freeGpuVector<REAL>(m_dphi_in_W_cen);
    common::freeGpuVector<REAL>(m_dpsi_in_W_cen);


    cudaStreamDestroy(m_stream1);
    cudaStreamDestroy(m_stream2);
    cudaStreamDestroy(m_stream3);
    cudaStreamDestroy(m_stream4);
    cudaStreamDestroy(m_stream5);
    cudaStreamDestroy(m_stream6);
    cudaStreamDestroy(m_stream7);
    cudaStreamDestroy(m_stream8);
    cudaStreamDestroy(m_stream9);
    cudaStreamDestroy(m_stream10);
    cudaStreamDestroy(m_stream11);
    cudaStreamDestroy(m_stream12);
}


int CudaIncomingWaves::maxNoWaves(const Array1D<int> *array)
{
    int maximum = 0;
    for (unsigned int i = 1; i <= array->size() - 2; ++i) {
        int value = *(array->getElements() + i);
        if (value > maximum) {
            maximum = value;
        }
    }
    return maximum;
}


void CudaIncomingWaves::initialize(const Array1D<int > *hwvin_N_count,
                                   const Array2D<REAL> *hwvin_N_ext_ampl,
                                   const Array2D<REAL> *hwvin_N_ext_phase,
                                   const Array2D<REAL> *hwvin_N_ext_freq,
                                   const Array2D<REAL> *hwvin_N_ext_facphi,
                                   const Array2D<REAL> *hwvin_N_ext_facpsi,
                                   const Array2D<REAL> *hwvin_N_cen_ampl,
                                   const Array2D<REAL> *hwvin_N_cen_phase,
                                   const Array2D<REAL> *hwvin_N_cen_freq,
                                   const Array2D<REAL> *hwvin_N_cen_facphi,
                                   const Array2D<REAL> *hwvin_N_cen_facpsi,
                                   const Array2D<REAL> *hwvin_N_int_ampl,
                                   const Array2D<REAL> *hwvin_N_int_phase,
                                   const Array2D<REAL> *hwvin_N_int_freq,
                                   const Array2D<REAL> *hwvin_N_int_facphi,
                                   const Array2D<REAL> *hwvin_N_int_facpsi,
                                   const Array1D<int > *hwvin_E_count,
                                   const Array2D<REAL> *hwvin_E_ext_ampl,
                                   const Array2D<REAL> *hwvin_E_ext_phase,
                                   const Array2D<REAL> *hwvin_E_ext_freq,
                                   const Array2D<REAL> *hwvin_E_ext_facphi,
                                   const Array2D<REAL> *hwvin_E_ext_facpsi,
                                   const Array2D<REAL> *hwvin_E_cen_ampl,
                                   const Array2D<REAL> *hwvin_E_cen_phase,
                                   const Array2D<REAL> *hwvin_E_cen_freq,
                                   const Array2D<REAL> *hwvin_E_cen_facphi,
                                   const Array2D<REAL> *hwvin_E_cen_facpsi,
                                   const Array2D<REAL> *hwvin_E_int_ampl,
                                   const Array2D<REAL> *hwvin_E_int_phase,
                                   const Array2D<REAL> *hwvin_E_int_freq,
                                   const Array2D<REAL> *hwvin_E_int_facphi,
                                   const Array2D<REAL> *hwvin_E_int_facpsi,
                                   const Array1D<int > *hwvin_S_count,
                                   const Array2D<REAL> *hwvin_S_ext_ampl,
                                   const Array2D<REAL> *hwvin_S_ext_phase,
                                   const Array2D<REAL> *hwvin_S_ext_freq,
                                   const Array2D<REAL> *hwvin_S_ext_facphi,
                                   const Array2D<REAL> *hwvin_S_ext_facpsi,
                                   const Array2D<REAL> *hwvin_S_cen_ampl,
                                   const Array2D<REAL> *hwvin_S_cen_phase,
                                   const Array2D<REAL> *hwvin_S_cen_freq,
                                   const Array2D<REAL> *hwvin_S_cen_facphi,
                                   const Array2D<REAL> *hwvin_S_cen_facpsi,
                                   const Array2D<REAL> *hwvin_S_int_ampl,
                                   const Array2D<REAL> *hwvin_S_int_phase,
                                   const Array2D<REAL> *hwvin_S_int_freq,
                                   const Array2D<REAL> *hwvin_S_int_facphi,
                                   const Array2D<REAL> *hwvin_S_int_facpsi,
                                   const Array1D<int > *hwvin_W_count,
                                   const Array2D<REAL> *hwvin_W_ext_ampl,
                                   const Array2D<REAL> *hwvin_W_ext_phase,
                                   const Array2D<REAL> *hwvin_W_ext_freq,
                                   const Array2D<REAL> *hwvin_W_ext_facphi,
                                   const Array2D<REAL> *hwvin_W_ext_facpsi,
                                   const Array2D<REAL> *hwvin_W_cen_ampl,
                                   const Array2D<REAL> *hwvin_W_cen_phase,
                                   const Array2D<REAL> *hwvin_W_cen_freq,
                                   const Array2D<REAL> *hwvin_W_cen_facphi,
                                   const Array2D<REAL> *hwvin_W_cen_facpsi,
                                   const Array2D<REAL> *hwvin_W_int_ampl,
                                   const Array2D<REAL> *hwvin_W_int_phase,
                                   const Array2D<REAL> *hwvin_W_int_freq,
                                   const Array2D<REAL> *hwvin_W_int_facphi,
                                   const Array2D<REAL> *hwvin_W_int_facpsi)
{
    m_maxN = maxNoWaves(hwvin_N_count);
    m_maxE = maxNoWaves(hwvin_E_count);
    m_maxS = maxNoWaves(hwvin_S_count);
    m_maxW = maxNoWaves(hwvin_W_count);

    common::setGpu1DVector<int >(m_dwvin_N_count,      hwvin_N_count);
    common::setGpuIWVector<REAL>(m_dwvin_N_ext_ampl,   m_Nc, hwvin_N_ext_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_ext_phase,  m_Nc, hwvin_N_ext_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_ext_freq,   m_Nc, hwvin_N_ext_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_ext_facphi, m_Nc, hwvin_N_ext_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_ext_facpsi, m_Nc, hwvin_N_ext_facpsi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_cen_ampl,   m_Nc, hwvin_N_cen_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_cen_phase,  m_Nc, hwvin_N_cen_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_cen_freq,   m_Nc, hwvin_N_cen_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_cen_facphi, m_Nc, hwvin_N_cen_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_cen_facpsi, m_Nc, hwvin_N_cen_facpsi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_int_ampl,   m_Nc, hwvin_N_int_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_int_phase,  m_Nc, hwvin_N_int_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_int_freq,   m_Nc, hwvin_N_int_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_int_facphi, m_Nc, hwvin_N_int_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_N_int_facpsi, m_Nc, hwvin_N_int_facpsi, NUMBER);

    common::setGpu1DVector<int >(m_dwvin_E_count,      hwvin_E_count);
    common::setGpuIWVector<REAL>(m_dwvin_E_ext_ampl,   m_Nr, hwvin_E_ext_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_ext_phase,  m_Nr, hwvin_E_ext_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_ext_freq,   m_Nr, hwvin_E_ext_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_ext_facphi, m_Nr, hwvin_E_ext_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_ext_facpsi, m_Nr, hwvin_E_ext_facpsi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_cen_ampl,   m_Nr, hwvin_E_cen_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_cen_phase,  m_Nr, hwvin_E_cen_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_cen_freq,   m_Nr, hwvin_E_cen_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_cen_facphi, m_Nr, hwvin_E_cen_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_cen_facpsi, m_Nr, hwvin_E_cen_facpsi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_int_ampl,   m_Nr, hwvin_E_int_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_int_phase,  m_Nr, hwvin_E_int_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_int_freq,   m_Nr, hwvin_E_int_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_int_facphi, m_Nr, hwvin_E_int_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_E_int_facpsi, m_Nr, hwvin_E_int_facpsi, NUMBER);

    common::setGpu1DVector<int >(m_dwvin_S_count,      hwvin_S_count);
    common::setGpuIWVector<REAL>(m_dwvin_S_ext_ampl,   m_Nc, hwvin_S_ext_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_ext_phase,  m_Nc, hwvin_S_ext_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_ext_freq,   m_Nc, hwvin_S_ext_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_ext_facphi, m_Nc, hwvin_S_ext_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_ext_facpsi, m_Nc, hwvin_S_ext_facpsi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_cen_ampl,   m_Nc, hwvin_S_cen_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_cen_phase,  m_Nc, hwvin_S_cen_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_cen_freq,   m_Nc, hwvin_S_cen_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_cen_facphi, m_Nc, hwvin_S_cen_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_cen_facpsi, m_Nc, hwvin_S_cen_facpsi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_int_ampl,   m_Nc, hwvin_S_int_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_int_phase,  m_Nc, hwvin_S_int_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_int_freq,   m_Nc, hwvin_S_int_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_int_facphi, m_Nc, hwvin_S_int_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_S_int_facpsi, m_Nc, hwvin_S_int_facpsi, NUMBER);

    common::setGpu1DVector<int >(m_dwvin_W_count,      hwvin_W_count);
    common::setGpuIWVector<REAL>(m_dwvin_W_ext_ampl,   m_Nr, hwvin_W_ext_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_ext_phase,  m_Nr, hwvin_W_ext_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_ext_freq,   m_Nr, hwvin_W_ext_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_ext_facphi, m_Nr, hwvin_W_ext_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_ext_facpsi, m_Nr, hwvin_W_ext_facpsi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_cen_ampl,   m_Nr, hwvin_W_cen_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_cen_phase,  m_Nr, hwvin_W_cen_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_cen_freq,   m_Nr, hwvin_W_cen_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_cen_facphi, m_Nr, hwvin_W_cen_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_cen_facpsi, m_Nr, hwvin_W_cen_facpsi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_int_ampl,   m_Nr, hwvin_W_int_ampl,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_int_phase,  m_Nr, hwvin_W_int_phase,  NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_int_freq,   m_Nr, hwvin_W_int_freq,   NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_int_facphi, m_Nr, hwvin_W_int_facphi, NUMBER);
    common::setGpuIWVector<REAL>(m_dwvin_W_int_facpsi, m_Nr, hwvin_W_int_facpsi, NUMBER);
}

